import React, { useEffect, useState } from "react";
import { Card, Form, Input, Button, Select, Table, Row, Col } from "antd";
import { useNavigate } from "react-router-dom";
import { SearchOutlined } from "@ant-design/icons";

// 引入请求api
import {
  getHospitalListRequest,
  getProvinceRequest,
  getCityOrDistrictRequest,
} from "@/api/hospital/hospitalList";

import type {
  getHosListSearchParamsType,
  hospitalListContentType,
  hospitalListItemsType,
  getProvinceReturnType,
} from "@/api/hospital/model/hospitalListTypes";

export default function HospitalList() {
  const navigate = useNavigate();

  const [form] = Form.useForm();

  //定义isLoading(table是否加载中)  控制表格是否处于加载中的状态
  const [isLoading, setIsLoading] = useState(false);
  //控制当前页码的状态
  const [page, setPage] = useState(1);
  //控制每页显示的条数
  const [limit, setLimit] = useState(3);
  //控制医院总数量
  const [total, setTotal] = useState(0);
  //控制查询时用户输入的表单参数
  const [searchParams, setSearchParams] = useState<getHosListSearchParamsType>(
    {}
  ); //初始值是空对象，用户输入的表单参数是可选的，也有可能没有，所以类型限制记得加？

  //控制省份的状态(保存省份数据)
  const [province, setProvince] = useState<getProvinceReturnType>([]);
  //控制市的数据
  const [cityList, setCityList] = useState<getProvinceReturnType>([]);
  //控制区/县的数据
  const [district, setDistrict] = useState<getProvinceReturnType>([]);
  //控制医院类型
  const [hospitalType, setHospitalType] = useState<getProvinceReturnType>([]);

  // Table组件标签中的dataSource属性就是用来接收请求到数据并把数据渲染到表格中去的，而每次请求得到的数据很可能不同，所以要给请求得到的表格数据定义一个状态。（随着状态改变而重新渲染虚拟DOM,从而重新渲染表格）
  //控制表格的数据
  const [hospitalList, setHospitalList] = useState<hospitalListContentType>([]);

  //刚加载组件的时候,发送医院列表的请求
  useEffect(() => {
    //在请求开始之前,设置isLoading为true
    setIsLoading(true);

    const getHospitalList = async () => {
      const result = await getHospitalListRequest(page, limit, searchParams);

      //把结果中的医院列表的数组设置给状态state
      setHospitalList(result.content);

      //把结果中的医院总数设置给状态state
      setTotal(result.totalElements);

      //请求完成后要把isLoading修改为false
      setIsLoading(false);
    };
    getHospitalList();
  }, [searchParams, page, limit]);

  //2.初始化的时候请求所有的省份
  useEffect(() => {
    const getProvince = async () => {
      const result = await getProvinceRequest();

      // 把得到的省份列表放在state中
      setProvince(result);
    };
    getProvince();
  }, []);

  // 3.初始化的时候立即请求医院类型
  useEffect(() => {
    const getHospitalType = async () => {
      const result = await getCityOrDistrictRequest("10000");

      //把医院类型设置给状态
      setHospitalType(result);
    };
    getHospitalType();
  }, []);

  //事件回调函数
  //1.选择省份的时候事件回调函数
  const changeProvinceHandle = async (value: string) => {
    //根据省份的value 发送获取市的请求
    const result = await getCityOrDistrictRequest(value);

    // 把拿到的市的数据设置给保存的state
    setCityList(result);

    //选择完省份的时候,把市和区目前的value清除掉  (让表单的name不再和数据的value一一对应，给name属性赋值为null。)
    form.setFieldsValue({ cityCode: null, districtCode: null });

    //清空区/县下拉框的数据
    setDistrict([]);
  };

  //2.选择城市的时候事件回调函数
  const cityChangeHandle = async (value: string) => {
    //select上面提供一个onChange事件，该事件接收的第一个参数就是当前所选市的value。
    //根据所选市的value 发送请求得到县的数据
    const result = await getCityOrDistrictRequest(value);

    //把结果交给state保管
    setDistrict(result);

    //选择完市的时候,把区目前的value清除掉  (让表单的name不再和数据的value一一对应，给name属性赋值为null。那么数据就不会渲染在表单中，在表单中显示了。)
    form.setFieldsValue({ districtCode: null });
  };

  // 3.点击查询表单的提交事件
  const finishHandle = (value: getHosListSearchParamsType) => {
    // console.log(value);
    setSearchParams(value); //点击查询按钮，收集表单信息，设置给状态保存，useEffect检测到setSearchParams（用户输入的表单数据）发生改变就重新执行，发出请求重新获取医院信息。
  };

  // 4.点击查询表单的清空按钮
  const clearSearchHandle = () => {
    // 点击清空，就把之前保存在状态上的表单数据清空,setSearchParams一发生改变，就会让useEffect监测到，从而重新发请求，获取医院列表，渲染页面。
    setSearchParams({});
  };

  // 5.点击查看按钮事件回调函数  （点击查看的时候要拿到当前行数据的id）
  const hospitalDetailHandle = (id: string) => {
    return () => {
      navigate(`/syt/hospital/hospitalShow/${id}`,{     //跳转路由,使用path路由传参把当前行数据的id带过去。
        //测试state传值(练习而已)
        state:{ hello: "world" }
      }); 
    };
  };

  // 表格字段
  const columns = [
    {
      title: "序号",
      width: 60,
      dataIndex: "index",
      render(_: any, __: any, index: number) {
        return index + 1;
      },
    },
    {
      title: "医院logo",
      //如果没有dataIndex设置,则render中拿到的数据就是当前完整的数据, 可以从完整数据中拿到logoData (使用data.logoData)
      /* render(_: any, data: any) {
        return (
          <img width={100} src={`data:image/jpeg;base64,${data.logoData}`} alt="" />
        )
      } */

      //如果设置了dataIndex,则render拿到的直接就是dataIndex对应的数据了，也就是说render的形参接收的就是logoData
      dataIndex: "logoData",
      render(logoData: string) {
        return (
          <img width={100} src={`data:image/jpeg;base64,${logoData}`} alt="" />
        );
      },
    },
    {
      title: "医院名称",
      dataIndex: "hosname",
    },
    {
      title: "等级",
      render(_: any, data: hospitalListItemsType) {
        return data.param.hostypeString;
      },
    },
    {
      title: "详细地址",
      render(_: any, data: hospitalListItemsType) {
        return data.param.fullAddress;
      },
    },
    {
      title: "状态", //状态也得用render,因为不是要把0或1放到表格中，而是要根据0和1显示不同的文字在表格上。
      render(_: any, data: hospitalListItemsType) {
        return data.status === 0 ? "下线" : "上线";
      },
    },
    {
      title: "创建时间",
      dataIndex: "createTime",
    },
    {
      title: "操作",
      width: 120,
      fixed: "right" as "right",
      dataIndex: "id",

      render(id: string) {
        //设置了dataIndex，那么render方法接收的参数就是dataIndex的值。也就是当前行数据的id。
        return (
          <div>
            <Button type="primary" onClick={hospitalDetailHandle(id)}>
              查看
            </Button>
            <Button type="primary">排班</Button>
            <Button type="primary">上线</Button>
          </div>
        );
      },
    },
  ];

  return (
    <div>
      <Card>
        <Form name="basic" form={form} onFinish={finishHandle}>
          {/* 这样只要拿form就能获取当前表单了 */}{" "}
          {/*Form里面有个setFieldsValue，设置好以后，它就会拿表单的name属性和数据一一去对应,把数据渲染在表单上。只要让表单name和数据不再一一对应就能断开数据在表单中的渲染（显示）。 */}
          <Row gutter={10}>
            <Col span={4}>
              <Form.Item name="provinceCode">
                <Select
                  placeholder="请输入省份"
                  allowClear
                  onChange={changeProvinceHandle}
                >
                  {province.map((item) => {
                    return (
                      <Select.Option value={item.value} key={item.id}>
                        {item.name}
                      </Select.Option>
                    );
                  })}
                </Select>
              </Form.Item>
            </Col>

            <Col span={4}>
              <Form.Item name="cityCode">
                <Select
                  placeholder="请输入市"
                  allowClear
                  onChange={cityChangeHandle}
                >
                  {cityList.map((item) => {
                    return (
                      <Select.Option value={item.value} key={item.id}>
                        {item.name}
                      </Select.Option>
                    );
                  })}
                </Select>
              </Form.Item>
            </Col>

            <Col span={4}>
              <Form.Item name="districtCode">
                <Select placeholder="请输入县/区" allowClear>
                  {district.map((item) => {
                    return (
                      <Select.Option value={item.value} key={item.id}>
                        {item.name}
                      </Select.Option>
                    );
                  })}
                </Select>
              </Form.Item>
            </Col>

            <Col span={4}>
              <Form.Item name="hosname">
                <Input placeholder="医院名称" />
              </Form.Item>
            </Col>

            <Col span={4}>
              <Form.Item name="hoscode">
                <Input placeholder="医院编号" />
              </Form.Item>
            </Col>

            <Col span={4}>
              <Form.Item name="hostype">
                <Select placeholder="医院类型" allowClear>
                  {hospitalType.map((item) => {
                    return (
                      <Select.Option value={item.value} key={item.id}>
                        {item.name}
                      </Select.Option>
                    );
                  })}
                </Select>
              </Form.Item>
            </Col>
          </Row>
          <Row gutter={10}>
            <Col span={4}>
              <Form.Item name="status">
                <Select placeholder="医院状态" allowClear>
                  <Select.Option value={1}>上线</Select.Option>
                  <Select.Option value={0}>下线</Select.Option>
                </Select>
              </Form.Item>
            </Col>

            <Col span={2}>
              <Form.Item>
                <Button
                  type="primary"
                  htmlType="submit"
                  icon={<SearchOutlined />}
                >
                  查询
                </Button>
              </Form.Item>
            </Col>

            <Col span={2} style={{ marginLeft: "20px" }}>
              <Form.Item>
                <Button
                  type="default"
                  htmlType="reset"
                  onClick={clearSearchHandle}
                >
                  清空
                </Button>
              </Form.Item>
            </Col>
          </Row>
        </Form>

        <Table
          style={{ marginTop: "30px" }}
          columns={columns}
          dataSource={hospitalList}
          scroll={{ x: 1100 }}
          bordered
          rowKey="id"
          loading={isLoading}
          pagination={{
            //页码的配置：当前页码
            current: page,
            //总数据的数量
            total: total,
            //每页条数
            pageSize: limit,
            //展示更改每页条数的选项(默认total大于50条的时候开启)
            pageSizeOptions: [3, 8, 15],
            //是否直接开启更新每页条数的选项
            showSizeChanger: true,

            showTotal(total) {
              return `总共有${total}条数据`;
            },

            onChange(page: number, pageSize: number) {
              // 当页码发生改变的时候就修改page和limit
              setPage(page);
              setLimit(pageSize);
            },
          }}
        />
      </Card>
    </div>
  );
}
